home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / utility / crypchal.zip / HI-CRYPT.C < prev    next >
C/C++ Source or Header  |  1994-04-17  |  6KB  |  251 lines

  1. /*
  2. **  HI-CRYPT.C - Enhanced security S-CODER file encryptor/decryptor
  3. **
  4. **  public domain demo by Bob Stout
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10.  
  11. /*
  12. **  Globals & prototypes from CRYPT.C, also in SNIPPETS
  13. */
  14.  
  15. extern char *cryptext;
  16. extern int  crypt_length, crypt_ptr;
  17. void crypt(unsigned char *);
  18. void bufcrypt(unsigned char *buf, long length);
  19.  
  20. /*
  21. **  Other SNIPPETS prototypes from CRC-16.C and CANT.C
  22. */
  23.  
  24. unsigned short  crc16(char *, unsigned short);
  25. FILE           *cant(char *, char *);
  26.  
  27. /*
  28. **  HI-CRYPT.C globals and prototypes
  29. */
  30.  
  31. int  cryptqual(void);         /* Qualify the key                  */
  32. void setup(void);             /* Set hide_loc, hide_ix, crypt_ptr */
  33. void shuffle(void);           /* Assymetrical block transposition */
  34. void encrypt(void);           /* Encrypt a file                   */
  35. void decrypt(void);           /* Decrypt a file                   */
  36. void usage(void);             /* Tell 'm how it works!            */
  37.  
  38. long     hide_loc;            /* Where we save the file length    */
  39. unsigned hide_ix;
  40.  
  41. FILE *infile, *outfile;
  42.  
  43. union {                       /* Transposition cipher block       */
  44.       char in[16384];
  45.       char proc[256][64];
  46.       char out[64][256];
  47. } buf;
  48.  
  49. union {                       /* Size of the plain text file      */
  50.       long len;
  51.       unsigned char blen[4];
  52. } fsize;
  53.  
  54. /*
  55. **  GO - Collect $200...
  56. */
  57.  
  58. main(int argc, char *argv[])
  59. {
  60.       if (5 > argc || NULL == strchr("EeDd", argv[1][0]))
  61.             usage();
  62.       infile = cant(argv[3], "rb");
  63.       outfile = cant(argv[4], "w+b");
  64.       cryptext = argv[2];
  65.       crypt_length = strlen(cryptext);
  66.       if (cryptqual())
  67.       {
  68.             puts("\aHI-CRYPT: Key is not sufficiently complex");
  69.             return EXIT_FAILURE;
  70.       }
  71.       if (strchr("Ee", argv[1][0]))
  72.             encrypt();
  73.       else  decrypt();
  74.       fclose(infile);
  75.       fclose(outfile);
  76.       return EXIT_SUCCESS;
  77. }
  78.  
  79. /*
  80. **  They goofed - tell 'em how it works!
  81. */
  82.  
  83. void usage(void)
  84. {
  85.       puts("\aUsage: HI-CRYPT { E | D } key input_file output_file");
  86.       puts("where: E = Encrypt");
  87.       puts("       D = Decrypt");
  88.       puts("NOTE : If the key contains spaces, it must be enclosed "
  89.             "in quotation marks");
  90.       exit(EXIT_FAILURE);
  91. }
  92.  
  93. /*
  94. **  The key must be 64 bits or more and contain at least 5 distinct chars
  95. */
  96.  
  97. int cryptqual(void)
  98. {
  99.       int i, j = 0;
  100.       static char found[6];
  101.  
  102.       memset(found, 0, 6);
  103.       if (8 > crypt_length)
  104.             return -1;
  105.       for (i = 0; i < crypt_length; ++i)
  106.       {
  107.             if (strchr(found, cryptext[i]))
  108.                   continue;
  109.             found[j++] = cryptext[i];
  110.             if (5 < j)
  111.                   return 0;
  112.       }
  113.       return -1;
  114. }
  115.  
  116. /*
  117. **  Scramble transposition block buffer
  118. */
  119.  
  120. void shuffle(void)
  121. {
  122.       int i;
  123.       static char buf2[16384];
  124.       char *p = buf2;
  125.  
  126.       for (i = 0; i < 64; ++i)
  127.       {
  128.             memcpy(p, buf.out[63 - i], 256);
  129.             p = &p[256];
  130.       }
  131.       memcpy(buf.in, buf2, 16384);
  132. }
  133.  
  134. /*
  135. **  Compute the location to save the file size
  136. */
  137.  
  138. void setup(void)
  139. {
  140.       unsigned short crc;
  141.  
  142.       crc = crc16(cryptext, crypt_length);
  143.       hide_ix = crc % (16384 - sizeof(long));
  144.       hide_loc = (long)(sizeof(long) + hide_ix);
  145.       crypt_ptr = crc % crypt_length;
  146.       srand(hide_ix);
  147. }
  148.  
  149. /*
  150. **  Encrypt a file
  151. */
  152.  
  153. void encrypt(void)
  154. {
  155.       unsigned i, j, n;
  156.       long swap1, swap2;
  157.  
  158.       /*
  159.       **  Get the file size
  160.       */
  161.  
  162.       setup();
  163.       fseek(infile, 0L, SEEK_END);
  164.       fsize.len = ftell(infile);
  165.       rewind(infile);
  166.  
  167.       /*
  168.       **  Encrypt & save the file size
  169.       */
  170.  
  171.       for (i = 0; i < sizeof(long); ++i)
  172.             crypt(&fsize.blen[i]);
  173.       fwrite(&fsize.len, sizeof(long), 1, outfile);
  174.  
  175.       /*
  176.       **  Encrypt the plaintext
  177.       */
  178.  
  179.       while (0 != (n = fread(buf.in, 1, 16384, infile)))
  180.       {
  181.             while (16384 > n)
  182.                   buf.in[n++] = rand();
  183.             for (i = 0; i < 64; ++i)
  184.             {
  185.                   for (j = 0; j < 256; ++j)
  186.                         crypt(&buf.proc[j][63 - i]);
  187.             }
  188.             shuffle();
  189.             fwrite(buf.in, 1, 16384, outfile);
  190.       }
  191.  
  192.       /*
  193.       **  Relocate the file size
  194.       */
  195.  
  196.       fseek(outfile, hide_loc, SEEK_SET);
  197.       fread(&swap2, sizeof(long), 1, outfile);
  198.       rewind(outfile);
  199.       fread(&swap1, sizeof(long), 1, outfile);
  200.       fseek(outfile, hide_loc, SEEK_SET);
  201.       fwrite(&swap1, sizeof(long), 1, outfile);
  202.       rewind(outfile);
  203.       fwrite(&swap2, sizeof(long), 1, outfile);
  204. }
  205.  
  206. /*
  207. **  Decrypt a file
  208. */
  209.  
  210. void decrypt(void)
  211. {
  212.       unsigned i, j, n;
  213.       int block_1 = -1;
  214.       long hide_buf;
  215.  
  216.       /*
  217.       **  Retrieve & decrypt the file size
  218.       */
  219.  
  220.       setup();
  221.       fseek(infile, hide_loc, SEEK_SET);
  222.       fread(&fsize.len, sizeof(long), 1, infile);
  223.       rewind(infile);
  224.       fread(&hide_buf, sizeof(long), 1, infile);
  225.       for (i = 0; i < sizeof(long); ++i)
  226.             crypt(&fsize.blen[i]);
  227.  
  228.       /*
  229.       **  Decrypt the ciphertext
  230.       */
  231.  
  232.       while (0 != (n = fread(buf.in, 1, 16384, infile)))
  233.       {
  234.             if (block_1)
  235.             {
  236.                   block_1 = 0;
  237.                   memcpy(&buf.in[hide_ix], &hide_buf, sizeof(long));
  238.             }
  239.             shuffle();
  240.             for (i = 0; i < 64; ++i)
  241.             {
  242.                   for (j = 0; j < 256; ++j)
  243.                         crypt(&buf.proc[j][63 - i]);
  244.             }
  245.             if (16384 <= fsize.len)
  246.                   fwrite(buf.in, 1, 16384, outfile);
  247.             else  fwrite(buf.in, 1, fsize.len, outfile);
  248.             fsize.len -= n;
  249.       }
  250. }
  251.